package com.canaan.business.service.bill.impl;

import cn.hutool.core.collection.CollUtil;
import com.canaan.business.common.enums.inOutStock.OutOrderStatusEnum;
import com.canaan.business.common.enums.inOutStock.OutStockOrderTypeEnum;
import com.canaan.business.domain.bill.PurchaseReturnBill;
import com.canaan.business.domain.inOutStock.WmsOutStockOrder;
import com.canaan.business.domain.vo.PurchaseReturnBillExportVo;
import com.canaan.business.mapper.bill.PurchaseReturnBillMapper;
import com.canaan.business.service.bill.IPurchaseReturnBillService;
import com.canaan.business.service.inOutStock.IWmsOutStockOrderService;
import com.canaan.common.exception.ServiceException;
import com.canaan.common.utils.DateUtils;
import com.canaan.common.utils.SecurityUtils;
import com.canaan.common.utils.StringUtils;
import com.canaan.common.utils.TableNoUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 采购退货单Service业务层处理
 *
 * @author ruoyi
 * @date 2023-03-13
 */
@Service
public class PurchaseReturnBillServiceImpl implements IPurchaseReturnBillService {
    @Resource
    private PurchaseReturnBillMapper purchaseReturnBillMapper;
    @Resource
    private IWmsOutStockOrderService wmsOutStockOrderService;

    /**
     * 查询采购退货单
     *
     * @param id 采购退货单主键
     * @return 采购退货单
     */
    @Override
    public PurchaseReturnBill selectPurchaseReturnBillById(Long id) {
        return purchaseReturnBillMapper.selectPurchaseReturnBillById(id);
    }

    /**
     * 查询采购退货单列表
     *
     * @param purchaseReturnBill 采购退货单
     * @return 采购退货单
     */
    @Override
    public List<PurchaseReturnBill> selectPurchaseReturnBillList(PurchaseReturnBill purchaseReturnBill) {
        return purchaseReturnBillMapper.selectPurchaseReturnBillList(purchaseReturnBill);
    }

    /**
     * 新增采购退货单
     *
     * @param purchaseReturnBill 采购退货单
     * @return 结果
     */
    @Override
    public int insertPurchaseReturnBill(PurchaseReturnBill purchaseReturnBill) {
        if(StringUtils.isBlank(purchaseReturnBill.getNo())){
            purchaseReturnBill.setNo(TableNoUtil.getNo(PurchaseReturnBill.class));
        }
        if(StringUtils.isEmpty(purchaseReturnBill.getCreateBy())) {
            purchaseReturnBill.setCreateBy(SecurityUtils.getUsername());
        }
        purchaseReturnBill.setCreateTime(DateUtils.getNowDate());
        purchaseReturnBill.setStatus(OutOrderStatusEnum.NEW.getCode());
        return purchaseReturnBillMapper.insertPurchaseReturnBill(purchaseReturnBill);
    }

    /**
     * 批量新增采购退货单
     *
     * @param purchaseReturnBillList 采购退货单列表
     * @return 结果
     */
    @Override
    public int batchInsertPurchaseReturnBill(List<PurchaseReturnBill> purchaseReturnBillList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (PurchaseReturnBill purchaseReturnBill : purchaseReturnBillList){
            if(StringUtils.isBlank(purchaseReturnBill.getNo())){
                purchaseReturnBill.setNo(TableNoUtil.getNo(PurchaseReturnBill.class));
            }
            purchaseReturnBill.setCreateBy(username);
            purchaseReturnBill.setCreateTime(currerTime);
        }
        int insertNum = 0;
        for (int i=0; i<purchaseReturnBillList.size();) {
            int endIndex = i+500;
            if (endIndex > purchaseReturnBillList.size()) {
                endIndex = purchaseReturnBillList.size();
            }
            insertNum = insertNum + purchaseReturnBillMapper.batchInsertPurchaseReturnBill(purchaseReturnBillList.subList(i, endIndex));
            i = endIndex;
        }
        return insertNum;
    }

    /**
     * 修改采购退货单
     *
     * @param purchaseReturnBill 采购退货单
     * @return 结果
     */
    @Override
    public int updatePurchaseReturnBill(PurchaseReturnBill purchaseReturnBill) {
        purchaseReturnBill.setUpdateBy(SecurityUtils.getUsername());
        purchaseReturnBill.setUpdateTime(DateUtils.getNowDate());
        return purchaseReturnBillMapper.updatePurchaseReturnBill(purchaseReturnBill);
    }

    /**
     * 批量修改采购退货单
     *
     * @param purchaseReturnBillList 采购退货单列表
     * @return 结果
     */
    @Override
    public int batchUpdatePurchaseReturnBill(List<PurchaseReturnBill> purchaseReturnBillList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (PurchaseReturnBill purchaseReturnBill : purchaseReturnBillList){
            purchaseReturnBill.setUpdateBy(username);
            purchaseReturnBill.setUpdateTime(currerTime);
        }
        int updateNum = 0;
        for (int i=0; i<purchaseReturnBillList.size();) {
            int endIndex = i+500;
            if (endIndex > purchaseReturnBillList.size()) {
                endIndex = purchaseReturnBillList.size();
            }
            updateNum = updateNum + purchaseReturnBillMapper.batchUpdatePurchaseReturnBill(purchaseReturnBillList.subList(i, endIndex));
            i = endIndex;
        }
        return updateNum;
    }

    /**
     * 批量删除采购退货单
     *
     * @param ids 需要删除的采购退货单主键集合
     * @return 结果
     */
    @Override
    public int deletePurchaseReturnBillByIds(Long[] ids) {
        PurchaseReturnBill bill = new PurchaseReturnBill();
        bill.setIds(CollUtil.toList(ids));
        List<PurchaseReturnBill> billList = this.selectPurchaseReturnBillList(bill);
        List<String> nos = billList.stream()
                .filter(e -> OutOrderStatusEnum.CANCEL_PENDING_CONFIRMATION.getCode().equals(e.getStatus())
                        || OutOrderStatusEnum.ACCOMPLISH.getCode().equals(e.getStatus()))
                .map(PurchaseReturnBill::getNo).collect(Collectors.toList());
        if(!nos.isEmpty()){
            throw new ServiceException("取消待确认或已完成状态的单据不能删除");
        }
        for (PurchaseReturnBill productBill : billList) {
            if(OutOrderStatusEnum.PICKING.getCode().equals(productBill.getStatus())){
                //校验进行中单据下的出入库单数据
                WmsOutStockOrder stockOrder = wmsOutStockOrderService.selectWmsOutStockOrderByRelOrderNo(productBill.getNo(), OutStockOrderTypeEnum.RETURN.getCode());
                if(stockOrder != null && stockOrder.getTotalActualQty() > 0){
                    nos.add(productBill.getNo());
                }
            }
        }
        if(!nos.isEmpty()){
            throw new ServiceException(nos + "单据已有实际出库数量不能删除");
        }
        //出库单和出库单明细删除
        nos = billList.stream().map(PurchaseReturnBill::getNo).collect(Collectors.toList());
        wmsOutStockOrderService.deleteWmsOutStockOrderByRelOrderNosAndType(nos, OutStockOrderTypeEnum.RETURN.getCode());
        return purchaseReturnBillMapper.deletePurchaseReturnBillByIds(ids);
    }

    /**
     * 删除采购退货单信息
     *
     * @param id 采购退货单主键
     * @return 结果
     */
    @Override
    public int deletePurchaseReturnBillById(Long id) {
        return purchaseReturnBillMapper.deletePurchaseReturnBillById(id);
    }

    /**
     * 查询采购退货单
     *
     * @param no 编号
     * @return 采购退货单
     */
    @Override
    public PurchaseReturnBill selectPurchaseReturnBillByNo(String no) {
        return purchaseReturnBillMapper.selectPurchaseReturnBillByNo(no);
    }

    /**
     * 批量删除采购退货单
     *
     * @param nos 需要删除的编号集合
     * @return 结果
     */
    @Override
    public int deletePurchaseReturnBillByNos(String[] nos) {
        return purchaseReturnBillMapper.deletePurchaseReturnBillByNos(nos);
    }

    /**
     * 删除采购退货单信息
     *
     * @param no 编号
     * @return 结果
     */
    @Override
    public int deletePurchaseReturnBillByNo(String no) {
        return purchaseReturnBillMapper.deletePurchaseReturnBillByNo(no);
    }

    /**
     * 确认取消
     * @param bill 单据信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int confirmCancel(PurchaseReturnBill bill) {
        bill = this.selectPurchaseReturnBillById(bill.getId());
        if(bill == null){
            throw new ServiceException("单据不存在");
        }else if(!OutOrderStatusEnum.CANCEL_PENDING_CONFIRMATION.getCode().equals(bill.getStatus())){
            throw new ServiceException("该状态不是取消待确认，无法确认取消");
        }

        WmsOutStockOrder stockOrder = wmsOutStockOrderService.selectWmsOutStockOrderByRelOrderNo(bill.getNo(), OutStockOrderTypeEnum.RETURN.getCode());
        if(stockOrder != null){
            stockOrder.setOrderStatus(OutOrderStatusEnum.CANCEL.getCode());
            wmsOutStockOrderService.updateWmsOutStockOrder(stockOrder);
        }
        bill.setStatus(OutOrderStatusEnum.CANCEL.getCode());
        return this.updatePurchaseReturnBill(bill);
    }

    /**
     * 导出列表
     *
     * @param purchaseReturnBill 采购退货单
     * @return 采购退货单导出集合
     */
    @Override
    public List<PurchaseReturnBillExportVo> exportList(PurchaseReturnBill purchaseReturnBill){
        return this.purchaseReturnBillMapper.exportList(purchaseReturnBill);
    }
}
